# coding: utf-8

from google.appengine.ext import db
import core.relatedkeyword
import data.provider
import core.utility

class SearchProducts:
    @staticmethod
    def exactSearch(keyword, area, providerid, startIndex, limit, expired):
        q = SearchProducts.queryBuinder(keyword, area, providerid, expired)
        return q.fetch(limit, startIndex)
    
    @staticmethod
    def relatedSearch(keyword, area, providerid, startIndex, limit, expired):
        # 인자로 전달된 keyword와 관련된 연관 검색어 조회
        related_keywords = core.relatedkeyword.RelatedKeyword.get(keyword)
        related_keywords.insert(0, keyword)
        
        retData = []
        bEnd = False
        local_start_offset = 0
        local_count = 0
        
        for word in related_keywords:
            results = SearchProducts.exactSearch(core.utility.Utility.convertEncoding(word), 
                                                 area, providerid, 0, 100, expired)
            
            for result in results:
                if bEnd:    break
                # 주어진 시작 인덱스까지 이동하였는지 확인
                if local_start_offset < startIndex: 
                    local_start_offset+=1
                    continue
                
                # 반환할 결과 집합에 조회된 결과를 추가
                retData.append(result)
                local_count+=1
                
                # limit보다 반환할 결과 집합에 데이터가 더 많으면 종료
                if local_count >= limit:
                    bEnd = True
            if bEnd:    break
            
        return retData, related_keywords
    
    @staticmethod
    def queryBuinder(keyword, area, providerid, expired):
        p = data.provider.Providers()
        if(keyword!="*"):                       # 검색 키워드가 입력된 경우
            keyword_end = keyword + u"\ufffd"
            if(area!="*"):                      # 검색 지역이 입력된 경우
                if(providerid!=p.AllProvider):  # 특정 업체를 지정하여 검색하는 경우
                    if(expired == 1):           # 판매 기간이 지난 상품까지 검색하는 경우
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND area = :3 AND social_provider_code = :4", 
                                        keyword, keyword_end, area, providerid)
                    else:   # 현재 팬마중인 상품만을 검색하는 경우
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND area = :3 AND social_provider_code = :4 \
                                        AND is_expired = 0", 
                                        keyword, keyword_end, area, providerid)
                else:       # 모든 업체를 검색하는 경우 
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND area = :3", 
                                        keyword, keyword_end, area)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND area = :3 AND is_expired = 0", 
                                        keyword, keyword_end, area)
            else: # area is *
                if(providerid!=p.AllProvider):
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND social_provider_code = :3", 
                                        keyword, keyword_end, providerid)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND social_provider_code = :3 AND is_expired = 0", 
                                        keyword, keyword_end, providerid)
                else:   # provider is *
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2", 
                                        keyword, keyword_end)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE keywords >= :1 AND keywords < :2 \
                                        AND is_expired = 0", 
                                        keyword, keyword_end)
        else: # keyword is *
            if(area!="*"):
                if(providerid!=p.AllProvider):
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE area = :1 AND social_provider_code = :2", 
                                        area, providerid)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE area = :1 AND social_provider_code = :2 \
                                        AND is_expired = 0", 
                                        area, providerid)
                else:   # provider is *
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products WHERE area = :1", area)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products WHERE area = :1 \
                                        AND is_expired = 0", area)
            else: # area is *
                if(providerid!=p.AllProvider):
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE social_provider_code = :1", providerid)
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE social_provider_code = :1 AND is_expired = 0", 
                                        providerid)
                else:   # provider is *
                    if(expired == 1):
                        q = db.GqlQuery("SELECT * FROM Products ORDER BY sell_delta DESC")
                    else:
                        q = db.GqlQuery("SELECT * FROM Products \
                                        WHERE is_expired = 0 ORDER BY sell_delta DESC")
        return q                